import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Weight-normalized Complement Naive Bayes 
 * @author alecmgo@gmail.com
 */
public class WCNBClassifier extends CNBClassifier {
  public WCNBClassifier(MessageIterator mi) {
    super(mi);
  }
  
  /**
   * Returns score using formula (8) of paper
   */
  double getScore(MessageFeatures message, int newsgroup) {
    double prior = Math.log(newsgroupPrior.getCount(newsgroup));
    double theta = 0;
    for(String term : message.body.keySet()) {
      theta -= Math.log(conditionalProbabilities.getCount(term, newsgroup));
    }
    double summedTheta = getWeightSummation(termCount.keySet(), newsgroup);

    //double score = prior + (theta / summedTheta);
    double score = (theta / summedTheta);
    //System.err.println(newsgroup + "\t" + prior + "\t" + theta + "\t" + summedTheta + "\t" + score);
    return score;
  }
  
  /**
   * Returns denominator as described in formula (8) of paper
   * @param terms
   * @param newsgroup
   * @return
   */

  Map<Integer, Double> weightCache = new HashMap<Integer, Double>();
  
  double getWeightSummation(Set<String> terms, int newsgroup) {
    if(weightCache.get(newsgroup) == null) {
      double summation = 0;
      for(String term : terms) {
        summation += Math.abs(Math.log(conditionalProbabilities.getCount(term, newsgroup)));
      }
      //System.err.println("Newsgroup " + newsgroup + " weight is: " + summation);
      weightCache.put(newsgroup, summation);
    }
    return weightCache.get(newsgroup);
  }  

  
}
